package org.madgecko.basic.util;

import org.apache.commons.beanutils.PropertyUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EnumUtils {
	@SuppressWarnings("rawtypes")
	public static List<Integer> enum2Ordinal(Class<? extends Enum> clz){
		if(!clz.isEnum()){
			return null;
		}
		List<Integer> l = new ArrayList<Integer>();
		for(Enum e : clz.getEnumConstants()){
			l.add(e.ordinal());
		}
		return l;
	}
	
	@SuppressWarnings("rawtypes")
	public static List<String> enum2Names(Class<? extends Enum> clz){
		if(!clz.isEnum()){
			return null;
		}
		List<String> l = new ArrayList<String>();
		for(Enum e : clz.getEnumConstants()){
			l.add(e.name());
		}
		return l;
	}
	
	@SuppressWarnings("rawtypes")
	public static Map<String, Object> enum2NameOrdinalMap(Class<? extends Enum> clz){
		if(!clz.isEnum()){
			return null;
		}
		Map<String, Object> m = new HashMap<String, Object>();
		for(Enum e : clz.getEnumConstants()){
			m.put(e.name(), e.ordinal());
		}
		return m;
	}
	
	@SuppressWarnings("rawtypes")
	public static List<String> enum2PropList(Class<? extends Enum> clz, String propName) {
		if(!clz.isEnum()){
			return null;
		}
		Enum[] enums = clz.getEnumConstants();
		List<String> vals = new ArrayList<String>();
		try {
			for(Enum e : enums){
				String  val = (String)PropertyUtils.getProperty(e, propName);
				vals.add(val);
			}
			return vals;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings("rawtypes")
	public static Map<Integer, String> enum2OrdinalPropMap(Class<? extends Enum> clz, String propName){
		if(!clz.isEnum()){
			return null;
		}
		Enum[] enums = clz.getEnumConstants();
		Map<Integer, String> ordinalMap = new HashMap<Integer, String>();
		
		try {
			for(Enum e : enums){
				String val = (String)PropertyUtils.getProperty(e, propName);
				ordinalMap.put(e.ordinal(), val);
			}
			return ordinalMap;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static Map<String, String> enum2NamePropMap(Class<? extends Enum> clz, String propName){
		if(!clz.isEnum()){
			return null;
		}
		Enum[] enums = clz.getEnumConstants();
		Map<String, String> m = new HashMap<String, String>();
		try {
			for(Enum e : enums){
				String prop = (String)PropertyUtils.getProperty(e, "name");
				m.put(e.name(), prop);
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		return m;
	}
	
	
	@SuppressWarnings("rawtypes")
	public static Map<String, String> enum2PropPropMap(Class<? extends Enum> clz, String propName, String valName){
		if(!clz.isEnum()){
			return null;
		}
		Enum[] enums = clz.getEnumConstants();
		Map<String, String> m = new HashMap<String, String>();
		
		try {
			for(Enum e : enums){
				String prop = (String)PropertyUtils.getProperty(e, propName);
				String val = (String)PropertyUtils.getProperty(e, valName);
				m.put(prop, val);
			}
			return m;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
		
		return null;
	}

	public static List<Object> enum2ObjList(Class<? extends Enum> clz, String enumDisplayProp, Class objClz, String objDisplayProp, String objValueProp){
		if(!clz.isEnum()){
			return null;
		}
		Enum[] enums = clz.getEnumConstants();
		List<Object> objList = new ArrayList<Object>();
		try {
			for(Enum e : enums){
				Object o = objClz.newInstance();
				PropertyUtils.setProperty(o, objDisplayProp, PropertyUtils.getProperty(e, enumDisplayProp));
				PropertyUtils.setProperty(o, objValueProp, e.name());
				objList.add(o);
			}
			return objList;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}catch (NoSuchMethodException e){
			e.printStackTrace();
		}catch (InvocationTargetException e){
			e.printStackTrace();
		}
		return null;
	}
}

